/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package analiseSintatica.Regras.Expressoes;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.ErroSemantico;
import analiseSemantica.Tipos.TipoSemantico;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.AnalisadorSintatico;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import java.util.LinkedList;

/**
 *
 * @author linton
 * nathy
 */
public class RegraExpAritmetica extends Regra{

    protected static Regra instancia;


    /**
     * Construtor privado necessario ao singleton
     */
    private RegraExpAritmetica() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraExpAritmetica getInstance() {
        if (instancia == null) {
            instancia = new RegraExpAritmetica();
        }
        return (RegraExpAritmetica) instancia;
    }

    //<exp_aritmetica> ::= <multiplicacao> {<op_adicao> <multiplicacao>} ok
    @Override
    public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
    	TiposSemanticos retorno;

        TiposSemanticos regra1 = RegraMultiplicacao.getInstance().analisar(listaTokens);
        retorno = regra1;
        
        while(listaContem(RegraOpAdicao.getInstance().getPrimeiro(), listaTokens.getFirst())){
        		RegraOpAdicao.getInstance().analisar(listaTokens);

        		TiposSemanticos regra2 = RegraMultiplicacao.getInstance().analisar(listaTokens);
                
        		if(retorno != null && regra2 != null){
	        	    TipoSemantico regraTipo = regra2.getFirst();
	                int linha = regraTipo.getLinha();
	                
	                if(!regraTipo.getNomeTipo().equals(retorno.getFirst().getTipo())){
	                	String frase = "Comparacao entre tipos diferentes: "+retorno.getFirst().getTipo() + "\te "+regraTipo.getNomeTipo();
	                	AnalisadorSintatico.errosemanticos.add(new ErroSemantico(frase,linha));
	                	retorno = null;
	                }
        		}else
        			retorno = null;
        }
        return retorno;
    }


    @Override
    protected void setPrimeiro() {
        this.primeiro = RegraMultiplicacao.getInstance().getPrimeiro();
    }
}
